package com.lalilu.lread.utils;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
import android.view.ViewPropertyAnimator;

import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class AlbumItemAnimator extends DefaultItemAnimator {
    private List<ScaleInfo> mPendingScaleInfos = new ArrayList<>();
    private long mAnimationDelay = 0;

    @Override
    public boolean animateRemove(RecyclerView.ViewHolder holder) {
        mAnimationDelay = getRemoveDuration();
        return super.animateRemove(holder);
    }

    @Override
    public boolean animatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preInfo,
                                      @NonNull ItemHolderInfo postInfo) {
        int preWidth = preInfo.right - preInfo.left;
        int preHeight = preInfo.bottom - preInfo.top;
        int postWidth = postInfo.right - postInfo.left;
        int postHeight = postInfo.bottom - postInfo.top;
        if (postWidth != 0 && postHeight != 0 && (preWidth != postWidth || preHeight != postHeight)) {
            float xScale = preWidth / (float) postWidth;
            float yScale = preHeight / (float) postHeight;
            viewHolder.itemView.setPivotX(0);
            viewHolder.itemView.setPivotY(0);
            viewHolder.itemView.setScaleX(xScale);
            viewHolder.itemView.setScaleY(yScale);
            mPendingScaleInfos.add(new ScaleInfo(viewHolder, xScale, yScale, 1, 1));
        }
        return super.animatePersistence(viewHolder, preInfo, postInfo);
    }

    private void animateScaleImpl(ScaleInfo info) {
        final View view = info.holder.itemView;
        final ViewPropertyAnimator animation = view.animate();
        animation.scaleX(info.toX);
        animation.scaleY(info.toY);
        animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mAnimationDelay = 0;
            }
        }).start();
    }

    @Override
    public void runPendingAnimations() {
        if (!mPendingScaleInfos.isEmpty()) {
            Runnable scale = () -> {
                for (ScaleInfo info : mPendingScaleInfos) {
                    animateScaleImpl(info);
                }
                mPendingScaleInfos.clear();
            };
            if (mAnimationDelay == 0) {
                scale.run();
            } else {
                View view = mPendingScaleInfos.get(0).holder.itemView;
                ViewCompat.postOnAnimationDelayed(view, scale, getRemoveDuration());
            }
        }
        super.runPendingAnimations();
    }

    private class ScaleInfo {
        public RecyclerView.ViewHolder holder;
        public float fromX, fromY, toX, toY;

        ScaleInfo(RecyclerView.ViewHolder holder, float fromX, float fromY, float toX, float toY) {
            this.holder = holder;
            this.fromX = fromX;
            this.fromY = fromY;
            this.toX = toX;
            this.toY = toY;
        }
    }
}